import { apiAddress as baseUrl } from '../utils/config'
import { autoCodeLogin, getToken, logout } from '../utils/permission'

const qs = require('qs')

const getUrl = (url) => {
  if (url.indexOf('://') == -1) {
    url = baseUrl + url
  }
  return url
}

/**
 * get 方法
 * @param relativeUrl 相对路径 必填
 * @param param 参数 可选
 * @param header 请求头参数 可选
 * @param stringify 是否将参数序列化
 * @returns {Promise}
 */
export const get = (relativeUrl, param, header, stringify = true) => {
  if (stringify) {
    relativeUrl = relativeUrl + '?' + qs.stringify(param)
    param = null
  }
  return requestWithModal('GET', relativeUrl, param, header, stringify)
}

/**
 * post 方法
 */
export const post = (relativeUrl, param, header, stringify = true) => {
  if (stringify) {
    param = qs.stringify(param)
  }
  return requestWithModal('POST', relativeUrl, param, header, stringify)
}

/**
 * put 方法
 */
export const put = (relativeUrl, param, header, stringify = true) => {
  if (stringify) {
    param = qs.stringify(param)
  }
  return requestWithModal('PUT', relativeUrl, param, header, stringify)
}

/**
 * del 方法
 */
export const del = (relativeUrl, param, header, stringify = true) => {
  if (stringify) {
    relativeUrl = relativeUrl + '?' + qs.stringify(param)
    param = null
  }
  return requestWithModal('DELETE', relativeUrl, param, header, stringify)
}

/**
 * 请求失败时，显示服务器的错误信息(data.message)或微信的错误信息(errMsg)
 * @param {string} method 请求方式 必填
 * @param {string} relativeUrl 相对路径 必填
 * @param {string} param 参数 可选
 * @param {Object} header 请求头参数 可选
 * @returns {Promise} 返回响应完整内容
 */
export function requestWithModal(method, relativeUrl, param, header) {
  return request(method, relativeUrl, param, header).catch((res) => {
    let errMsg
    if (res.data && res.data.msg) {
      errMsg = res.data.msg
    } else {
      errMsg = res.statusCode ? '发生未知错误，请联系开发者' : res.errMsg
    }
    wx.showModal({
      content: errMsg,
      showCancel: false
    })
    return Promise.reject(res)
  })
}

/**
 * request 基类方法
 * 状态码 ≥ 400 时，返回 rejected 状态的 promise
 * @param method 请求方式 必填
 * @param relativeUrl 相对路径 必填
 * @param param 参数 可选
 * @param header 请求头参数 可选
 * @returns {Promise} 返回响应完整内容
 */
export function request(method, relativeUrl, param, header) {
  // 删除所有为 null 的参数
  // for (var key in param) {
  //   if (param[key] === null) {
  //     delete param[key]
  //   }
  // }

  let response, error
  return new Promise((resolve, reject) => {
    wx.request({
      url: getUrl(relativeUrl),
      method: method,
      header: Object.assign(
        {
          Authorization: getToken(),
          Accept: 'application/json, text/plain, */*',
          'content-type': 'application/x-www-form-urlencoded'
        },
        header
      ),
      data: param || {},
      success(res) {
        response = res.data
        if (res.statusCode < 400 && response && response.code === 200) {
          resolve(response)
        } else if (response.code === 401) {
          wx.showModal({
            title: '提示',
            content: '首次登录需要授权，请手动登录',
            showCancel: false
          }).then(() => {
            logout()
            wx.reLaunch({ url: '/pages/list/list' })
          })
          reject(res)
        } else if (response.code === 402) {
          // getApp().autoCodeLogin();
          wx.showModal({
            title: '提示',
            content: getToken() ? '您需要重新登录' : '您还没有登录',
            showCancel: false
          }).then(() => {
            logout()
            wx.reLaunch({
              url: '/pages/list/list',
              success: () => {
                getApp().autoCodeLogin()
              }
            })
          })
          resolve(response)
        } else {
          reject(res)
        }
      },
      fail(err) {
        error = err
        reject(err)
      },
      complete() {
        console.info('==============>请求开始<==============')
        console.warn(method, getUrl(relativeUrl))
        if (param) console.warn('参数：', param)
        if (response) {
          console.warn('请求成功：', response)
        } else {
          console.warn('请求失败：', error)
        }
        console.info('==============>请求结束<==============')
      }
    })
  })
}
